using System;
using System.Collections.Generic;

namespace Game.Network {
    public abstract class UDPPacket: Packet {
        protected byte[] m_buffer;
        
        public enum UDPPacketType {
            EveryFrame,
            XTimes,
            Never
        };
        
        private UDPPacketType m_sendPolicy;
        public UDPPacketType SendPolicy{ get { return m_sendPolicy; } }
        
        private int m_sendTimes;
        public int SendTimes{ get { return m_sendTimes; } }
        
        protected UDPPacket(int packetID, int length, UDPPacketType policy = UDPPacketType.EveryFrame, int times = 1){
            m_buffer = new byte[length];
            m_buffer [0] = (byte)packetID;
            m_sendTimes = times;
            m_sendPolicy = policy;
            lock (m_sliceLock) {
                m_packets [packetID] = this;
                if(m_lastPacket < packetID)
                    m_lastPacket = packetID;
            }
        }
        
        public byte[] GetSendBuffer(bool subtract = true){
            if (m_sendPolicy == UDPPacketType.XTimes) {
                if(subtract)
                    m_sendTimes--;
                
                if (m_sendTimes <= 0) {
                    m_sendPolicy = UDPPacketType.Never;
                    return null;
                }
            } else if (m_sendPolicy == UDPPacketType.Never) {
                return null;
            }
            
            if (m_buffer.Length == 0)
                return null;
            
            return m_buffer;
        }
        
        private static UDPPacket[] m_packets = new UDPPacket[0x100];
        private static int m_lastPacket = -1;
        public static UDPPacket[] Packets{ get { return m_packets; } }
        protected static object m_sliceLock = new object();
        
        public static List<byte[]> GetPacketSlice(bool subtract = true) {
            List<byte[]> result = new List<byte[]> ();
            lock (m_sliceLock) {
                for (int i = 0; i <= m_lastPacket; i++) {
                    if (m_packets [i] != null) {
                        byte[] p = m_packets [i].GetSendBuffer (subtract);
                        if (p != null)
                            result.Add (p);
                    }
                }
            }
            return result;
        }
    }
}

